Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit 09db4a93287dd59bc9097e64b4fba9c2149f8766


Parents : 6b2cf01
Author : Mark Qvist <mark@unsigned.io>
Date : 2025-02-18T16:13:57+01:00

Removed library

Changes
Diff

diff --git a/sbapp/md2bbcode/__init__.py b/sbapp/md2bbcode/__init__.py
deleted file mode 100644
index e69de29b..00000000

diff --git a/sbapp/md2bbcode/html2bbcode.py b/sbapp/md2bbcode/html2bbcode.py
deleted file mode 100644
index 98fd830c..00000000
--- a/sbapp/md2bbcode/html2bbcode.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# converts some HTML tags to BBCode
-# pass --debug to save the output to readme.finalpass
-# may be better off replacing this with html to markdown (and then to bbcode). Lepture recommeds a JS html to markdown converter: sundown
-from bs4 import BeautifulSoup, NavigableString
-import argparse
-
-def handle_font_tag(tag, replacements):
- """Handles the conversion of <font> tag with attributes like color and size."""
- attributes = []
- if 'color' in tag.attrs:
- attributes.append(f"COLOR={tag['color']}")
- if 'size' in tag.attrs:
- attributes.append(f"SIZE={tag['size']}")
- if 'face' in tag.attrs:
- attributes.append(f"FONT={tag['face']}")
-
- inner_content = ''.join(recursive_html_to_bbcode(child, replacements) for child in tag.children)
- if attributes:
- # Nest all attributes. Example: [COLOR=red][SIZE=5]content[/SIZE][/COLOR]
- for attr in reversed(attributes):
- inner_content = f"[{attr}]{inner_content}[/{attr.split('=')[0]}]"
- return inner_content
-
-def handle_style_tag(tag, replacements):
- """Handles the conversion of tags with style attributes like color, size, and font."""
- attributes = []
- style = tag.attrs.get('style', '')
-
- # Extracting CSS properties
- css_properties = {item.split(':')[0].strip(): item.split(':')[1].strip() for item in style.split(';') if ':' in item}
-
- # Mapping CSS properties to BBCode
- if 'color' in css_properties:
- attributes.append(f"COLOR={css_properties['color']}")
- if 'font-size' in css_properties:
- attributes.append(f"SIZE={css_properties['font-size']}")
- if 'font-family' in css_properties:
- attributes.append(f"FONT={css_properties['font-family']}")
- if 'text-decoration' in css_properties and 'line-through' in css_properties['text-decoration']:
- attributes.append("S") # Assume strike-through
- if 'text-decoration' in css_properties and 'underline' in css_properties['text-decoration']:
- attributes.append("U")
- if 'font-weight' in css_properties:
- if css_properties['font-weight'].lower() == 'bold' or (css_properties['font-weight'].isdigit() and int(css_properties['font-weight']) >= 700):
- attributes.append("B") # Assume bold
-
- inner_content = ''.join(recursive_html_to_bbcode(child, replacements) for child in tag.children)
- if attributes:
- # Nest all attributes
- for attr in reversed(attributes):
- if '=' in attr: # For attributes with values
- inner_content = f"[{attr}]{inner_content}[/{attr.split('=')[0]}]"
- else: # For simple BBCode tags like [B], [I], [U], [S]
- inner_content = f"[{attr}]{inner_content}[/{attr}]"
- return inner_content
-
-def recursive_html_to_bbcode(element):
- """Recursively convert HTML elements to BBCode."""
- bbcode = ''
-
- if isinstance(element, NavigableString):
- bbcode += str(element)
- elif element.name == 'details':
- # Handle <details> tag
- summary = element.find('summary')
- spoiler_title = ''
- if summary:
- # Get the summary content and remove the summary element
- spoiler_title = '=' + ''.join([recursive_html_to_bbcode(child) for child in summary.contents])
- summary.decompose()
-
- # Process remaining content
- content = ''.join([recursive_html_to_bbcode(child) for child in element.contents])
- bbcode += f'[SPOILER{spoiler_title}]{content}[/SPOILER]'
- elif element.name == 'summary':
- # Skip summary tag as it's handled in details
- return ''
- else:
- # Handle other tags or pass through
- content = ''.join([recursive_html_to_bbcode(child) for child in element.contents])
- bbcode += content
-
- return bbcode
-
-def html_to_bbcode(html):
- replacements = {
- 'b': 'B',
- 'strong': 'B',
- 'i': 'I',
- 'em': 'I',
- 'u': 'U',
- 's': 'S',
- 'sub': 'SUB',
- 'sup': 'SUP',
- 'p': '', # Handled by default
- 'ul': 'LIST',
- 'ol': 'LIST=1',
- 'li': '*', # Special handling in recursive function
- 'font': '', # To be handled for attributes
- 'blockquote': 'QUOTE',
- 'pre': 'CODE',
- 'code': 'ICODE',
- 'a': 'URL', # Special handling for attributes
- 'img': 'IMG' # Special handling for attributes
- }
-
- soup = BeautifulSoup(html, 'html.parser')
- return recursive_html_to_bbcode(soup)
-
-def process_html(input_html, debug=False, output_file=None):
- converted_bbcode = html_to_bbcode(input_html)
-
- if debug:
- with open(output_file, 'w', encoding='utf-8') as file:
- file.write(converted_bbcode)
- else:
- return converted_bbcode
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Convert HTML to BBCode with optional debugging output.")
- parser.add_argument('input_file', type=str, help='Input HTML file path')
- parser.add_argument('--debug', action='store_true', help='Save output to readme.finalpass for debugging')
-
- args = parser.parse_args()
- input_file = args.input_file
- output_file = 'readme.finalpass' if args.debug else None
-
- with open(input_file, 'r', encoding='utf-8') as file:
- html_content = file.read()
-
- # Call the processing function
- process_html(html_content, debug=args.debug, output_file=output_file)
\ No newline at end of file

diff --git a/sbapp/md2bbcode/main.py b/sbapp/md2bbcode/main.py
deleted file mode 100644
index c001366e..00000000
--- a/sbapp/md2bbcode/main.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# uses a custom mistune renderer to convert Markdown to BBCode. The custom renderer is defined in the bbcode.py file.
-# pass --debug to save the output to readme.1stpass (main.py) and readme.finalpass (html2bbcode)
-# for further debugging, you can convert the markdown file to AST using md2ast.py. Remember to load the plugin(s) you want to test.
-
-#standard library
-import argparse
-import sys
-import RNS
-
-# mistune
-import mistune
-from mistune.plugins.formatting import strikethrough, mark, superscript, subscript, insert
-from mistune.plugins.table import table, table_in_list
-from mistune.plugins.footnotes import footnotes
-from mistune.plugins.task_lists import task_lists
-from mistune.plugins.def_list import def_list
-from mistune.plugins.abbr import abbr
-from mistune.plugins.spoiler import spoiler
-
-if RNS.vendor.platformutils.is_android():
- from .plugins.merge_lists import merge_ordered_lists
- from .renderers.bbcode import BBCodeRenderer
- from .html2bbcode import process_html
-else:
- from sbapp.md2bbcode.plugins.merge_lists import merge_ordered_lists
- from sbapp.md2bbcode.renderers.bbcode import BBCodeRenderer
- from sbapp.md2bbcode.html2bbcode import process_html
-
-def convert_markdown_to_bbcode(markdown_text, domain):
- # Create a Markdown parser instance using the custom BBCode renderer
- markdown_parser = mistune.create_markdown(renderer=BBCodeRenderer(domain=domain), plugins=[strikethrough, mark, superscript, subscript, insert, table, footnotes, task_lists, def_list, abbr, spoiler, table_in_list, merge_ordered_lists])
-
- # Convert Markdown text to BBCode
- return markdown_parser(markdown_text)
-
-def process_readme(markdown_text, domain=None, debug=False):
- # Convert Markdown to BBCode
- bbcode_text = convert_markdown_to_bbcode(markdown_text, domain)
-
- # Convert BBCode formatted as HTML to final BBCode
- final_bbcode = process_html(bbcode_text, debug, 'readme.finalpass')
-
- return final_bbcode
-
-def main():
- parser = argparse.ArgumentParser(description='Convert Markdown file to BBCode with HTML processing.')
- parser.add_argument('input', help='Input Markdown file path')
- parser.add_argument('--domain', help='Domain to prepend to relative URLs')
- parser.add_argument('--debug', action='store_true', help='Output intermediate results to files for debugging')
- args = parser.parse_args()
-
- if args.input == '-':
- # Read Markdown content from stdin
- markdown_text = sys.stdin.read()
- else:
- with open(args.input, 'r', encoding='utf-8') as md_file:
- markdown_text = md_file.read()
-
- # Process the readme and get the final BBCode
- final_bbcode = process_readme(markdown_text, args.domain, args.debug)
-
- # Optionally, print final BBCode to console
- if not args.debug:
- print(final_bbcode)
-
-if __name__ == '__main__':
- main()

diff --git a/sbapp/md2bbcode/md2ast.py b/sbapp/md2bbcode/md2ast.py
deleted file mode 100644
index 9ffe6485..00000000
--- a/sbapp/md2bbcode/md2ast.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# this is for debugging the custom mistune renderer bbcode.py
-import argparse
-import mistune
-import json # Import the json module for serialization
-from mistune.plugins.formatting import strikethrough, mark, superscript, subscript, insert
-from mistune.plugins.table import table, table_in_list
-from mistune.plugins.footnotes import footnotes
-from mistune.plugins.task_lists import task_lists
-from mistune.plugins.def_list import def_list
-from mistune.plugins.abbr import abbr
-from mistune.plugins.spoiler import spoiler
-
-#local
-from sbapp.md2bbcode.plugins.merge_lists import merge_ordered_lists
-
-def convert_markdown_to_ast(input_filepath, output_filepath):
- # Initialize Markdown parser with no renderer to produce an AST
- markdown_parser = mistune.create_markdown(renderer=None, plugins=[strikethrough, mark, superscript, subscript, insert, table, footnotes, task_lists, def_list, abbr, spoiler, table_in_list, merge_ordered_lists])
-
- # Read the input Markdown file
- with open(input_filepath, 'r', encoding='utf-8') as md_file:
- markdown_text = md_file.read()
-
- # Convert Markdown text to AST
- ast_text = markdown_parser(markdown_text)
-
- # Serialize the AST to a JSON string
- ast_json = json.dumps(ast_text, indent=4)
-
- # Write the output AST to a new file in JSON format
- with open(output_filepath, 'w', encoding='utf-8') as ast_file:
- ast_file.write(ast_json)
-
-def main():
- # Create argument parser
- parser = argparse.ArgumentParser(description='Convert Markdown file to AST file (JSON format).')
- # Add arguments
- parser.add_argument('input', help='Input Markdown file path')
- parser.add_argument('output', help='Output AST file path (JSON format)')
- # Parse arguments
- args = parser.parse_args()
-
- # Convert the Markdown to AST using the provided paths
- convert_markdown_to_ast(args.input, args.output)
-
-if __name__ == '__main__':
- main()

diff --git a/sbapp/md2bbcode/plugins/merge_lists.py b/sbapp/md2bbcode/plugins/merge_lists.py
deleted file mode 100644
index 5f499e17..00000000
--- a/sbapp/md2bbcode/plugins/merge_lists.py
+++ /dev/null
@@ -1,83 +0,0 @@
-from typing import Dict, Any, List
-
-def merge_ordered_lists(md):
- """
- A plugin to merge consecutive "top-level" ordered lists into one,
- and also attach any intervening code blocks or blank lines to the
- last list item so that the final BBCode appears as a single list
- with multiple steps.
-
- This relies on a few assumptions:
- 1) The only tokens between two ordered lists that should be merged
- are code blocks or blank lines (not normal paragraphs).
- 2) We want any code block(s) right after a list item to appear in
- that same bullet item.
- """
-
- def rewrite_tokens(md, state):
- tokens = state.tokens
- merged = []
- i = 0
-
- while i < len(tokens):
- token = tokens[i]
-
- # Check if this token is a top-level ordered list
- if (
- token["type"] == "list"
- and token.get("attrs", {}).get("ordered", False)
- and token.get("attrs", {}).get("depth", 0) == 0
- ):
- # Start new merged list
- current_depth = token["attrs"]["depth"]
- list_items = list(token["children"]) # bullet items in the first list
- i += 1
-
- # Continue until we run into something that's not:
- # another top-level ordered list,
- # or code blocks / blank lines (which we'll attach to the last bullet).
- while i < len(tokens):
- nxt = tokens[i]
-
- # If there's another ordered list at the same depth, merge its bullet items
- if (
- nxt["type"] == "list"
- and nxt.get("attrs", {}).get("ordered", False)
- and nxt.get("attrs", {}).get("depth", 0) == current_depth
- ):
- list_items.extend(nxt["children"])
- i += 1
-
- # If there's a code block or blank line, attach it to the *last* bullet item.
- elif nxt["type"] in ["block_code", "blank_line"]:
- if list_items: # attach to last bullet item, if any
- list_items[-1]["children"].append(nxt)
- i += 1
-
- else:
- # Not a same-depth list or code block—stop merging
- break
-
- # Create single merged list token
- merged.append(
- {
- "type": "list",
- "children": list_items,
- "attrs": {
- "ordered": True,
- "depth": current_depth,
- },
- }
- )
-
- else:
- # If not a top-level ordered list, just keep it as-is
- merged.append(token)
- i += 1
-
- # Replace the old tokens with the merged version
- state.tokens = merged
-
- # Attach to before_render_hooks so we can manipulate tokens before rendering
- md.before_render_hooks.append(rewrite_tokens)
- return md
\ No newline at end of file

diff --git a/sbapp/md2bbcode/renderers/__init__.py b/sbapp/md2bbcode/renderers/__init__.py
deleted file mode 100644
index e69de29b..00000000

diff --git a/sbapp/md2bbcode/renderers/bbcode.py b/sbapp/md2bbcode/renderers/bbcode.py
deleted file mode 100644
index f8cf2662..00000000
--- a/sbapp/md2bbcode/renderers/bbcode.py
+++ /dev/null
@@ -1,240 +0,0 @@
-from mistune.core import BaseRenderer
-from mistune.util import escape as escape_text, striptags, safe_entity
-from urllib.parse import urljoin, urlparse
-
-
-class BBCodeRenderer(BaseRenderer):
- """A renderer for converting Markdown to BBCode."""
- _escape: bool
- NAME = 'bbcode'
-
- def __init__(self, escape=False, domain=None):
- super(BBCodeRenderer, self).__init__()
- self._escape = escape
- self.domain = domain
-
- def render_token(self, token, state):
- func = self._get_method(token['type'])
- attrs = token.get('attrs')
-
- if 'raw' in token:
- text = token['raw']
- elif 'children' in token:
- text = self.render_tokens(token['children'], state)
- else:
- if attrs:
- return func(**attrs)
- else:
- return func()
-
- if attrs:
- return func(text, **attrs)
- else:
- return func(text)
-
- def safe_url(self, url: str) -> str:
- # Simple URL sanitization
- if url.startswith(('javascript:', 'vbscript:', 'data:')):
- return '#harmful-link'
- # Check if the URL is absolute by looking for a netloc part in the URL
- if not urlparse(url).netloc:
- url = urljoin(self.domain, url)
- return url
-
- def text(self, text: str) -> str:
- if self._escape:
- return escape_text(text)
- return text
-
- def emphasis(self, text: str) -> str:
- return '[i]' + text + '[/i]'
-
- def strong(self, text: str) -> str:
- return '[b]' + text + '[/b]'
-
- def link(self, text: str, url: str, title=None) -> str:
- return '[url=' + self.safe_url(url) + ']' + text + '[/url]'
-
- def image(self, text: str, url: str, title=None) -> str:
- alt_text = f' alt="{text}"' if text else ''
- img_tag = f'[img{alt_text}]' + self.safe_url(url) + '[/img]'
- # Check if alt text starts with 'pixel' and treat it as pixel art
- if text and text.lower().startswith('pixel'):
- return f'[pixelate]{img_tag}[/pixelate]'
- return img_tag
-
- def codespan(self, text: str) -> str:
- return '[icode]' + text + '[/icode]'
-
- def linebreak(self) -> str:
- return '\n'
-
- def softbreak(self) -> str:
- return '\n'
-
- def inline_html(self, html: str) -> str:
- if self._escape:
- return escape_text(html)
- return html
-
- def paragraph(self, text: str) -> str:
- return text + '\n\n'
-
- def heading(self, text: str, level: int, **attrs) -> str:
- if 1 <= level <= 3:
- return f"[HEADING={level}]{text}[/HEADING]\n"
- else:
- # Handle cases where level is outside 1-3
- return f"[HEADING=3]{text}[/HEADING]\n"
-
- def blank_line(self) -> str:
- return ''
-
- def thematic_break(self) -> str:
- return '[hr][/hr]\n'
-
- def block_text(self, text: str) -> str:
- return text
-
- def block_code(self, code: str, **attrs) -> str:
- # Renders blocks of code using the language specified in Markdown
- special_cases = {
- 'plaintext': None # Default [CODE]
- }
-
- if 'info' in attrs:
- lang_info = safe_entity(attrs['info'].strip())
- lang = lang_info.split(None, 1)[0].lower()
- # Check if the language needs special handling
- bbcode_lang = special_cases.get(lang, lang) # Use the special case if it exists, otherwise use lang as is
- if bbcode_lang:
- return f"[CODE={bbcode_lang}]{escape_text(code)}[/CODE]\n"
- else:
- return f"[CODE]{escape_text(code)}[/CODE]\n"
- else:
- # No language specified, render with a generic [CODE] tag
- return f"[CODE]{escape_text(code)}[/CODE]\n"
-
- def block_quote(self, text: str) -> str:
- return '[QUOTE]\n' + text + '[/QUOTE]\n'
-
- def block_html(self, html: str) -> str:
- if self._escape:
- return '<p>' + escape_text(html.strip()) + '</p>\n'
- return html + '\n'
-
- def block_error(self, text: str) -> str:
- return '[color=red][icode]' + text + '[/icode][/color]\n'
-
- def list(self, text: str, ordered: bool, **attrs) -> str:
- depth = 0; sln = ""; tli = ""
- if "depth" in attrs: depth = attrs["depth"]
- if depth != 0: sln = "\n"
- if depth == 0: tli = "\n"
- def remove_empty_lines(text):
- lines = text.split('\n')
- non_empty_lines = [line for line in lines if line.strip() != '']
- nli = ""; dlm = "\n"+" "*depth
- if depth != 0: nli = dlm
- return nli+dlm.join(non_empty_lines)
-
- text = remove_empty_lines(text)
-
- return sln+text+"\n"+tli
- # return '[{}]'.format(tag) + text + '[/list]\n'
-
- def list_item(self, text: str) -> str:
- return '• ' + text + '\n'
-
- def strikethrough(self, text: str) -> str:
- return '[s]' + text + '[/s]'
-
- def mark(self, text: str) -> str:
- # Simulate the mark effect with a background color in BBCode
- return '[mark]' + text + '[/mark]'
-
- def insert(self, text: str) -> str:
- # Use underline to represent insertion
- return '[u]' + text + '[/u]'
-
- def superscript(self, text: str) -> str:
- return '[sup]' + text + '[/sup]'
-
- def subscript(self, text: str) -> str:
- return '[sub]' + text + '[/sub]'
-
- def inline_spoiler(self, text: str) -> str:
- return '[ISPOILER]' + text + '[/ISPOILER]'
-
- def block_spoiler(self, text: str) -> str:
- return '[SPOILER]\n' + text + '\n[/SPOILER]'
-
- def footnote_ref(self, key: str, index: int):
- # Use superscript for the footnote reference
- return f'[sup][u][JUMPTO=fn-{index}]{index}[/JUMPTO][/u][/sup]'
-
- def footnotes(self, text: str):
- # Optionally wrap all footnotes in a specific section if needed
- return '[b]Footnotes:[/b]\n' + text
-
- def footnote_item(self, text: str, key: str, index: int):
- # Define the footnote with an anchor at the end of the document
- return f'[ANAME=fn-{index}]{index}[/ANAME]. {text}'
-
- def table(self, children, **attrs):
- # Starting with a full-width table by default if not specified
- # width = attrs.get('width', '100%') # comment out until XF 2.3
- # return f'[TABLE width="{width}"]\n' + children + '[/TABLE]\n' # comment out until XF 2.3
- return '[TABLE]\n' + children + '[/TABLE]\n'
-
- def table_head(self, children, **attrs):
- return '[TR]\n' + children + '[/TR]\n'
-
- def table_body(self, children, **attrs):
- return children
-
- def table_row(self, children, **attrs):
- return '[TR]\n' + children + '[/TR]\n'
-
- def table_cell(self, text, align=None, head=False, **attrs):
- # BBCode does not support direct cell alignment,
- # use [LEFT], [CENTER], or [RIGHT] tags
-
- # Use th for header cells and td for normal cells
- tag = 'TH' if head else 'TD'
-
- # Initialize alignment tags
- alignment_start = ''
- alignment_end = ''
-
- if align == 'center':
- alignment_start = '[CENTER]'
- alignment_end = '[/CENTER]'
- elif align == 'right':
- alignment_start = '[RIGHT]'
- alignment_end = '[/RIGHT]'
- elif align == 'left':
- alignment_start = '[LEFT]'
- alignment_end = '[/LEFT]'
-
- return f'[{tag}]{alignment_start}{text}{alignment_end}[/{tag}]\n'
-
- def task_list_item(self, text: str, checked: bool = False) -> str:
- # Using emojis to represent the checkbox
- checkbox_emoji = '󰱒' if checked else '󰄱'
- return checkbox_emoji + ' ' + text + '\n'
-
- def def_list(self, text: str) -> str:
- # No specific BBCode tag for <dl>, so we just use the plain text grouping
- return '\n' + text + '\n'
-
- def def_list_head(self, text: str) -> str:
- return '[b]' + text + '[/b]' + ' ' + ':' + '\n'
-
- def def_list_item(self, text: str) -> str:
- return '[INDENT]' + text + '[/INDENT]\n'
-
- def abbr(self, text: str, title: str) -> str:
- if title:
- return f'[abbr={title}]{text}[/abbr]'
- return text
\ No newline at end of file


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────